package snippets.cse524.activeDates;

import java.util.Comparator;

import org.apache.commons.lang3.StringUtils;

class Link {

	class LinkComparator implements Comparator<Link> {
		@Override
		public int compare(Link left, Link right) {
			if (left.beginYear != -1 && right.beginYear != -1) {
				if (left.beginYear < right.beginYear) {
					return -1;
				} else if (left.beginYear > right.beginYear) {
					return 1;
				}
			}

			if (left.endYear != -1 && right.endYear != -1) {
				if (right.endYear < right.endYear) {
					return -1;
				} else if (right.endYear > right.endYear) {
					return 1;
				}
			}

			return left == right ? 0 : -1;
		}
	}

	static class TitleComparator implements Comparator<Link> {
		@Override
		public int compare(Link o1, Link o2) {
			return o1.title.compareTo(o2.title);
		}
	}

	public final String title;
	public final int beginYear, endYear;

	public Link(String _title, int _beginYear, int _endYear) {
		this.title = _title;
		this.beginYear = _beginYear;
		this.endYear = _endYear;
	}

	public Link(String title) {
		this(title, -1, -1);
	}

	@Override
	public String toString() {
		return (this.title + " " + this.toYearsString()).trim();
	}

	public String toYearsString() {
		StringBuffer sb = new StringBuffer();
		if (beginYear != -1) {
			sb.append("(" + beginYear);
		}

		if (endYear != -1) {
			if (beginYear == -1) {
				sb.append("(?");
			}
			sb.append(" - " + endYear + ")");
		} else if (beginYear != -1) {
			sb.append(" - ?)");
		}

		return sb.toString().trim();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + beginYear;
		result = prime * result + endYear;
		result = prime * result + ((title == null) ? 0 : title.hashCode());
		return result;
	}

	public boolean before(Link other) {
		if (beginYear != -1 && other.beginYear != -1
				&& beginYear < other.beginYear)
			return true;

		if (endYear != -1 && other.endYear != -1 && endYear < other.endYear)
			return true;

		if (beginYear != -1 && other.beginYear == -1 && other.endYear != -1
				&& beginYear < other.endYear)
			return true;

		if (endYear != -1 && other.endYear == -1 && other.beginYear != -1
				&& endYear < other.beginYear)
			return true;

		return false;
	}

	public boolean within(Link other) {
		if ((beginYear == -1 || other.beginYear == -1 || (beginYear != -1
				&& other.beginYear != -1 && beginYear >= other.beginYear))
				&& (endYear == -1 || other.endYear == -1 || (endYear != -1
						&& other.endYear != -1 && endYear <= other.endYear)))
			return true;

		return false;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Link other = (Link) obj;
		if (beginYear != other.beginYear)
			return false;
		if (endYear != other.endYear)
			return false;
		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;
		return true;
	}

	public boolean equalsApproximate(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Link other = (Link) obj;

		// Allows one of the dates to be unknown
		if (beginYear != -1 && other.beginYear != -1
				&& beginYear != other.beginYear)
			return false;
		if (endYear != -1 && other.endYear != -1 && endYear != other.endYear)
			return false;

		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;
		return true;
	}

	public boolean equalsByTitle(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Link other = (Link) obj;

		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;

		return true;
	}

}